package com.cskaoyan.service;


import com.cskaoyan.bean.*;
import com.cskaoyan.bo.LoginBO;
import com.cskaoyan.mapper.AdminMapper;
import com.cskaoyan.mapper.PermissionDetailMapper;
import com.cskaoyan.mapper.PermissionMapper;
import com.cskaoyan.mapper.RoleMapper;
import com.cskaoyan.vo.InfoVO;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.Valid;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class AuthServiceImpl implements AuthService {
    @Autowired
    ObjectMapper objectMapper;

    @Autowired
    AdminMapper adminMapper;

    @Autowired
    RoleMapper roleMapper;

    @Autowired
    PermissionMapper permissionMapper;

    @Autowired
    PermissionDetailMapper permissionDetailMapper;

    @Override
    public long login(@Valid LoginBO data) {

        AdminExample adminExample = new AdminExample();
        AdminExample.Criteria criteria = adminExample.createCriteria();
        criteria.andUsernameEqualTo(data.getUsername());
        criteria.andPasswordEqualTo("PASSWORD('" + data.getPassword() + "')");
        criteria.andDeletedEqualTo(false);
        long count = adminMapper.countByExample(adminExample);
        return count;
    }

    @Override
    public InfoVO queryByUsername(String username) {
        AdminExample adminExample = new AdminExample();
        AdminExample.Criteria criteria = adminExample.createCriteria();
        criteria.andUsernameEqualTo(username);

        List<Admin> admins = adminMapper.selectByExample(adminExample);
        assert admins.size() == 1;
        Admin admin = admins.get(0);

        InfoVO infoVO = new InfoVO();
        Integer[] roles = admin.getRoleIds();

        infoVO.setName(admin.getUsername());
        infoVO.setAvatar(admin.getAvatar());

        List<Integer> roleIdList = Arrays.stream(roles).collect(Collectors.toList());

        if (!roleIdList.isEmpty()) {
            RoleExample roleExample = new RoleExample();
            RoleExample.Criteria roleExampleCriteria = roleExample.createCriteria();
            roleExampleCriteria.andIdIn(roleIdList);
            List<Role> roleList = roleMapper.selectByExample(roleExample);
            List<String> names = roleList.stream().map(Role::getName).collect(Collectors.toList());
            infoVO.setRoles(names);

            PermissionExample permissionExample = new PermissionExample();
            PermissionExample.Criteria permissionExampleCriteria = permissionExample.createCriteria();
            permissionExampleCriteria.andRoleIdIn(roleIdList);
            List<Permission> permissionList = permissionMapper.selectByExample(permissionExample);

            List<PermissionDetail> permissionDetailList = new ArrayList<>();
            for (Permission permission : permissionList) {
                PermissionDetailExample permissionDetailExample = new PermissionDetailExample();
                permissionDetailExample.createCriteria().andPermissionEqualTo(permission.getPermission());
                List<PermissionDetail> permissionDetail = permissionDetailMapper.selectByExample(permissionDetailExample);
                assert permissionDetail.size() <= 1;
                permissionDetailList.add(permissionDetail.get(0));
            }


            List<String> permissions = permissionDetailList.stream().map(PermissionDetail::getApi).collect(Collectors.toList());

            infoVO.setPerms(permissions);

        }
        return infoVO;
    }

    @Override
    public String queryPasswordByname(String username) {
        String password = adminMapper.selectpasswordByUsername(username);
        return password;
    }

    @Transactional
    @Override
    public void updateHostAndLoginTime(String host, Date lastAccessTime, String username) {
        Admin admin = new Admin();
        admin.setLastLoginIp(host);
        admin.setLastLoginTime(lastAccessTime);
        admin.setUpdateTime(lastAccessTime);
        AdminExample adminExample = new AdminExample();
        adminExample.createCriteria().andUsernameEqualTo(username);
        adminMapper.updateByExampleSelective(admin, adminExample);
    }
}
